#include "util.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>

void flushEscapeSequence(char escape_sequence[]) {
	escape_sequence[0] = 0;
	escape_sequence[1] = 0;
	escape_sequence[2] = 0;
}

int specialChar(char escape_sequence[]) {
	if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 65) {
		flushEscapeSequence(escape_sequence);	
		return UP;
	} else if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 66) {
		flushEscapeSequence(escape_sequence);
		return DOWN;
	} else if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 67) {
		flushEscapeSequence(escape_sequence);
		return RIGHT;
	} else if(escape_sequence[0] == 27 && escape_sequence[1] == 91 && escape_sequence[2] == 68) {
		flushEscapeSequence(escape_sequence);
		return LEFT;
	} else if(escape_sequence[0] == 12 || escape_sequence[1] == 12 || escape_sequence[2] == 12) {
		flushEscapeSequence(escape_sequence);
		return CTRL_L;
	}

	return -1;

}

char * readLine(char *init, directoryList dir, listHistory hist) {
	char *buffer; /* Buffer que recebe as entradas do teclado, vai sendo expandido dinâmicamente */
	char escape_sequence[3] = {0,0,0}; /* Vetor que armazena sequencias de escape */
	char c;
	int escapeIndex = 0; /* Inidice do vetor de sequencias de escape */
	int buffer_current_size = BUFFER_INIT_SIZE; /* Tamanho inicial do buffer */
	int specialCharCode;
	int i;	
	int initSize;
	nodeHistory nodeHist=NULL;
	char *current_dir = getcwd(NULL,0); /* Pega o diretório de trabalho atual */
	struct winsize ws; /* Guarda informações sobre o terminal */

	/* Pegando propriedades do terminal, estamos interessados no número de colunas */
	ioctl(1, TIOCGWINSZ, &ws);

	/* Essa parte foi escrita para ser usada no comando history, não é mais usado */
	if(init != NULL) {
		initSize = strlen(init);
		buffer = (char *)malloc((initSize+1)*sizeof(char));
		buffer_current_size = initSize+1;
		strcpy(buffer,init);
		i = initSize;
	} else {	
		buffer = (char *)malloc(BUFFER_INIT_SIZE*sizeof(char));
		i = 0;
	}

	
	printf("%s :: ",current_dir);	
	while((c = getchar()) != '\n') {

		escape_sequence[escapeIndex++] = c;
		if(escape_sequence[0] != 27) {
			escapeIndex = 0;
			flushEscapeSequence(escape_sequence);
		}

		if(escapeIndex > 2) {
			escapeIndex = 0;
		}
		specialCharCode = specialChar(escape_sequence);
		if(specialCharCode != -1) {
			if(specialCharCode == UP) {
				if(nodeHist == NULL) {
                                	nodeHist = hist->head;
                                 	if(nodeHist != NULL) {
                                         	printf("\r%s :: %s",current_dir,nodeHist->string);
                                         	printSpaces(ws.ws_col - strlen(current_dir) - strlen(nodeHist->string) - 4);
                                         	strcpy(buffer,nodeHist->string);
						i = strlen(buffer);
                                 	}
                         	} else if(nodeHist->next != NULL) {
                                 	nodeHist = nodeHist->next;
                                	printf("\r%s :: %s",current_dir,nodeHist->string);
                                 	printSpaces(ws.ws_col - strlen(current_dir) - strlen(nodeHist->string) - 4);
					strcpy(buffer,nodeHist->string);
					i = strlen(buffer);
                         	}

			} else if(specialCharCode == DOWN) {
				if(nodeHist != NULL) {
                                 	if(nodeHist->prev != NULL) {
                                         	nodeHist = nodeHist->prev;
                                         	printf("\r%s :: %s",current_dir,nodeHist->string);
                                         	printSpaces(ws.ws_col - strlen(current_dir) - strlen(nodeHist->string) - 4);
						strcpy(buffer,nodeHist->string);
						i = strlen(buffer);
                                 	}
                         	}
			} else if(specialCharCode == LEFT) {
				printf("%c[1D",27);

			}
		} else if(escape_sequence[0] != 27) {
			if(c >= 32 && c <= 126) {
				printf("%c",c);
				buffer[i++] = c;
			} else if(c == 13) {
				printf("%c",c);
				break;
			} else if(c == 127 && i > 0) {
				printf("\b \b");
				i--;
			} else if(c == 9) { /* TAB */
				searchIndex index;
				char *lastWord;
				buffer[i] = '\0';

				lastWord = getLastWord(buffer);
				index = search(dir,getLastWord(buffer));
				
				if(index->size == 1) {
					int ind = strlen(dir->list[index->v[0]]) - strlen(lastWord);
					int j = ind-1;
					ind += i;
					for(;i<ind;i++) {
						buffer[i] = (dir->list[index->v[0]])[j++];
						printf("%c",buffer[i]);
					}
				} else {
					int j;
					
					printf("\n\r");
					for(j=0;j<index->size;j++) {
						printf("%d. %s\n\r",j+1,dir->list[index->v[j]]);
					}	
				}
			} else if(c == 12) {
				char *r = (char *)malloc(6*sizeof(char));
				strcpy(r,"clear");
				return r;
			}
		}

		if(i == buffer_current_size) {
			int increase_factor = buffer_current_size/4;
			buffer = (char *)realloc(buffer,(buffer_current_size + increase_factor)*sizeof(char));
			buffer_current_size += increase_factor;
		}
	}
	buffer[i] = '\0';
	
	escapeIndex = 0;
	return buffer;
}


char * getLastWord(char *s) {
	char *r;

	int size = strlen(s);
	int i,j,k,count;

	i = size-1;
	if(s[i] == ' ') {
		while(s[i] == ' ' && i >= 0) {
			size--;
			i--;
		}
	}	

	if(i == 0) {
		return NULL;
	}

	for(i=size-1;i>=0;i--) {
		if(s[i] == ' ') {
			j = i+1;
			break;	
		}
		count++;
	}

	if(i == -1) {
		j = 0;
	}

	r = (char *)malloc((count+1)*sizeof(char));
	

	for(i=j,k=0;i<size;i++) {
		r[k++] = s[i];
	}
	r[k] = '\0';

	return r;	
}

void printSpaces(int n) {
        int i;

        for(i = 0;i<n;i++) {
                printf(" ");
        }
        for(i = 0;i<n;i++) {
                printf("\b");
        }
}

